import { store } from '@/store/setup'
import { defineStore } from 'pinia'
import { useMessage } from '@/hooks'
import { designUtils } from './utils'
import { useCloneNodeInfo } from './utils/clone'

import {
  BwCustomComFrontTypeEnum,
  type BwCustomComStructModel,
  type BwCustomComEmitInfoModel,
  type BwCustomComPropInfoModel,
  type BwCustomComNodeAttrModel,
  type BwCustomComPropSetConfig,
  type BwCustomComSlotInfoModel,
  type BwCustomComDesignInfoModel,
  type BwCustomComNodeIfInfoModel,
  type BwCustomComNodeForInfoModel,
  type BwCustomComNodeEventInfoModel,
  type BwCustomComNodeEnableSlotInfoModel,
} from '@bitwit/base-com-render'

import type { BwDesignDragNodeSortModel } from './utils/model'
import type { BwDesignDragAddNodeModel } from './utils/add/model'
import type { SysCustomComInfoOutupu } from './utils/axios/model'

import type { BwCustomComDesignStoreModel } from './model'

const { createWarningModal, createErrorModal } = useMessage()
const useComDesignStore = defineStore({
  id: 'BwCurtomComDesignStore',
  state: (): BwCustomComDesignStoreModel => ({
    selectNodeEle: null,
    curDesignInfo: null,
    curHideNodeIds: [],
    curCustomComList: [],
    curCustomComRenderInfo: {},
    curFrontType: BwCustomComFrontTypeEnum.pc,
  }),
  getters: {
    /** 获取当前设计组件设计信息 */
    getDesignInfo(): BwCustomComDesignInfoModel | null {
      const designInfo = this.curDesignInfo
      return designInfo
    },

    /** 获取当前设计组件Dom树 */
    getStructList(): Array<BwCustomComStructModel> {
      const curFront = this.curFrontType
      const designStructsInfo = this.curDesignInfo?.structs ?? {}
      const structs = designStructsInfo[curFront] ?? []
      return structs
    },

    /** 获取当前设计组件自定义逻辑 */
    getSetupLogic(): string {
      const curFront = this.curFrontType
      const designSetupInfo = this.curDesignInfo?.setup ?? {}

      // console.log('获取当前设计组件自定义逻辑', designSetupInfo, curFront)

      return designSetupInfo[curFront] ?? ''
    },

    /** 获取当前设计组件样式 */
    getComCss(): string | null {
      const curFront = this.curFrontType
      const designCssInfo = this.curDesignInfo?.comCss ?? {}
      const comCss = designCssInfo[curFront]

      return comCss ?? null
    },
  },
  actions: {
    /** 设置当前组件的配置端 */
    setFrontType(front: BwCustomComFrontTypeEnum) {
      this.curFrontType = front
    },

    /** 设置自定义组件列表 */
    setCustomComList(list: Array<SysCustomComInfoOutupu>) {
      this.curCustomComList = list
    },

    /** 设置自定义组件渲染信息 */
    setCustomComRenderInfo(pageId: string, data: BwCustomComDesignInfoModel) {
      this.curCustomComRenderInfo[pageId] = data
    },

    /** 设置当前组件的设计信息 */
    setDesignInfo(info: Nullable<BwCustomComDesignInfoModel>) {
      this.curDesignInfo = designUtils.infoDesignInfo(info)
    },

    /** 设计当前组件的 Css */
    setDesignComCss(curCss: Nullable<string>) {
      const curFront = this.curFrontType
      this.curDesignInfo = designUtils.infoDesignInfo(this.curDesignInfo)
      const designCssInfo = this.curDesignInfo?.comCss ?? {}

      designCssInfo[curFront] = curCss
      this.curDesignInfo.comCss = designCssInfo
    },

    /** 设置当前设计组件的 DOM 结构*/
    setDesignStructs(structs: Array<BwCustomComStructModel>) {
      const curFront = this.curFrontType
      this.curDesignInfo = designUtils.infoDesignInfo(this.curDesignInfo)
      const designStructsInfo = this.curDesignInfo?.structs ?? {}

      designStructsInfo[curFront] = structs
      this.curDesignInfo.structs = designStructsInfo
    },

    /** 设置当前设计组件的自定义逻辑 */
    setDesignSetupLogic(setupLogic: string) {
      const curFront = this.curFrontType

      this.curDesignInfo = designUtils.infoDesignInfo(this.curDesignInfo)
      const designSetupInfo = this.curDesignInfo?.setup ?? {}

      designSetupInfo[curFront] = setupLogic
      this.curDesignInfo.setup = designSetupInfo
    },

    /**
     * 设置当前设计组件Dom树
     * @param structs                    UI信息
     */
    setStructList(structs: Array<BwCustomComStructModel>) {
      const curFront = this.curFrontType
      if (this.curDesignInfo) {
        const designStructsInfo = this.curDesignInfo.structs
        designStructsInfo[curFront] = structs
        this.curDesignInfo.structs = designStructsInfo
      }
    },

    /**
     * 修改Dom节点名称
     * @param nodeId                  节点ID
     * @param nodeName                节点名称
     */
    onChangeNodeName(nodeId: string, nodeName: string) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId ?? '')
        nodeInfo
          ? (nodeInfo.node.nodeName = nodeName)
          : createErrorModal({
              content: '无法获取到节点元素， 修改节点名称失败，请检查！',
            })
      }
    },

    /**
     * 修改Dom节点事件回调
     * @param nodeId                  节点ID
     * @param info                    回调信息
     */
    onChangeNodeEvent(nodeId: string, info: BwCustomComNodeEventInfoModel) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId ?? '')
        if (nodeInfo) {
          const events = nodeInfo.node.events ?? []
          const index = events.findIndex((n) => n.eventCode === info.eventCode)

          index >= 0 ? (events[index] = info) : events.push(info)
          nodeInfo.node.events = events
        }
      }
    },

    /**
     * 选中Dom节点信息
     * @param nodeId                  节点ID
     */
    onSeleteNodeInfo(nodeId?: string) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId ?? '')
        this.selectNodeEle = nodeInfo?.node ?? null
      }
    },

    /**
     * 克隆节点元素
     * @param nodeId                  节点ID
     */
    onCopyNodeEle(nodeId: string) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId)
        if (nodeInfo) {
          const { list, node, index } = nodeInfo
          const copyEle = useCloneNodeInfo(node)

          list.splice(index + 1, 0, copyEle)
          this.setDesignStructs(structs)
          this.onSeleteNodeInfo(copyEle.nodeId)
        }
      }
    },

    /**
     * 移除节点元素
     * @param nodeId                  节点ID
     */
    onRemoveNodeEle(nodeId: string) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId)
        if (nodeInfo && nodeInfo.index >= 0) {
          nodeInfo.list.splice(nodeInfo.index, 1)

          this.setDesignStructs(structs)
          this.onSeleteNodeInfo()
        }
      }
    },

    /**
     * 隐藏节点元素
     * @param nodeId                  节点ID
     * @param isHide                  是否隐藏
     */
    onHideNodeEle(nodeId: string, isHide: boolean) {
      const list = this.curHideNodeIds
      const index = list.findIndex((n) => n === nodeId)

      index >= 0
        ? !isHide && list.splice(index, 1)
        : isHide && list.push(nodeId)
    },

    /** 拖拽节点元素排序 */
    onDragNodeEleSort(data: BwDesignDragNodeSortModel) {
      if (this.curDesignInfo) {
        const structs = this.getStructList
        const { nodeId, pNodeId, slotKey, newIndex } = data

        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId ?? '')
        const pNodeInfo = designUtils.findDomNodeInfo(structs, pNodeId ?? '')
        if (nodeInfo && pNodeInfo && slotKey) {
          const { node: pEle } = pNodeInfo
          const { node, list, index } = nodeInfo

          if (newIndex > index) {
            pEle.children = pEle?.children ?? {}

            if (slotKey) {
              const pChild = pEle.children[slotKey] ?? []
              node.parentNodeId = pNodeId ?? ''
              pChild.splice(newIndex ?? 0, 0, node)

              pEle.children[slotKey] = pChild
            }
            list.splice(index, 1)
          } else {
            list.splice(index, 1)
            pEle.children = pEle?.children ?? {}

            if (slotKey) {
              const pChild = pEle.children[slotKey] ?? []
              node.parentNodeId = pNodeId ?? ''
              pChild.splice(newIndex ?? 0, 0, node)

              pEle.children[slotKey] = pChild
            }
          }
        }
      }
    },

    /** 拖拽新增节点元素 */
    onDragAddNodeEle(data: BwDesignDragAddNodeModel) {
      const structs = this.getStructList

      if (Array.isArray(structs)) {
        const toNodeType = data.toNodeType

        /** 判断是否拖拽到设计器画布上 */
        if (toNodeType === 'canvas') {
          const newIndex = data.newIndex ?? 0
          designUtils
            .createDesignNodeEle(data)
            .then((newNode) => {
              newIndex
                ? structs.splice(newIndex, 0, newNode)
                : structs.push(newNode)
            })
            .catch((error) => {
              createErrorModal({ content: error })
            })
        } else {
          const nodeInfo = designUtils.findDomNodeInfo(structs, data.toNodeId)
          if (nodeInfo) {
            const curNode = nodeInfo.node
            const children = curNode.children ?? {}
            const slotCode = data.toNodeSlotCode

            designUtils
              .createDesignNodeEle(data)
              .then((newNode) => {
                if (slotCode in children) {
                  const childStructs = children[slotCode] ?? []
                  const newIndex = data.newIndex ?? 0

                  newIndex
                    ? childStructs.splice(newIndex, 0, newNode)
                    : childStructs.push(newNode)
                  children[slotCode] = childStructs
                } else {
                  children[slotCode] = [newNode]
                }

                curNode.children = children
              })
              .catch((error) => {
                createErrorModal({ content: error })
              })
          }
        }
      }
    },

    /** 修改节点元素属性 */
    onChangeNodeEleAttrs(
      nodeId: string,
      attrs?: Record<string, BwCustomComNodeAttrModel>
    ) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId)
        if (nodeInfo && nodeInfo.index >= 0) {
          nodeInfo.node.attrs = attrs ?? null
        }
      }
    },

    /** 修改节点元素 If 信息 */
    onChangeNodeEleIfInfo(nodeId: string, info?: BwCustomComNodeIfInfoModel) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId)
        if (nodeInfo && nodeInfo.index >= 0) {
          nodeInfo.node.nodeIfInfo = info
        }
      }
    },

    /** 修改节点元素 for 信息 */
    onChangeNodeEleForInfo(nodeId: string, info?: BwCustomComNodeForInfoModel) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId)
        if (nodeInfo && nodeInfo.index >= 0) {
          nodeInfo.node.nodeForInfo = info
        }
      }
    },

    /** 修改节点元素样式配置 */
    onChangeNodeEleStyle(nodeId: string, style?: Record<string, string>) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId)
        if (nodeInfo && nodeInfo.index >= 0) {
          nodeInfo.node.style = style ?? null
        }
      }
    },

    /** 修改节点元素自定义样式 */
    onChangeNodeEleCss(nodeId: string, css?: string) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId)
        if (nodeInfo && nodeInfo.index >= 0) {
          nodeInfo.node.css = css ?? null
        }
      }
    },

    /** 修改节点元素启用插槽 */
    onChangeEnableNodeSlot(
      nodeId: string,
      data: BwCustomComNodeEnableSlotInfoModel,
      visible: boolean
    ) {
      const structs = this.getStructList
      if (Array.isArray(structs) && structs.length) {
        const nodeInfo = designUtils.findDomNodeInfo(structs, nodeId)
        if (nodeInfo && nodeInfo.index >= 0) {
          const nodeSlots = nodeInfo.node.enableSlotList ?? []
          const item = designUtils.findComSlotInfo(nodeSlots, data)
          if (item.info) {
            item.info.visible = visible
          } else {
            nodeSlots.push(data)
          }
          nodeInfo.node.enableSlotList = nodeSlots
        }
      }
    },

    /** 新增组件外放事件 */
    onAddEmit(data: BwCustomComEmitInfoModel) {
      return new Promise<void>((resolve, reject) => {
        if (this.curDesignInfo) {
          const emits = this.curDesignInfo.emits ?? []
          const item = emits.find((n) => n.key === data.key)
          if (!item) {
            emits.push(data)
            this.curDesignInfo.emits = emits
            resolve()
          } else {
            reject()
            createWarningModal({ content: '当前事件已存在，请检查!' })
          }
        } else {
          reject()
          createWarningModal({ content: '没有获取到设计器信息，请检查!' })
        }
      })
    },

    /** 修改组件外放事件 */
    onEditEmit(
      oldData: BwCustomComEmitInfoModel,
      newData: BwCustomComEmitInfoModel
    ) {
      return new Promise<void>((resolve, reject) => {
        if (this.curDesignInfo) {
          const emits = this.curDesignInfo.emits ?? []
          const index = emits.findIndex((n) => n.key === oldData.key)
          if (index >= 0) {
            emits[index] = newData
            this.curDesignInfo.emits = emits
            resolve()
          } else {
            reject()
            createWarningModal({ content: '当前修改的事件不存在，请检查!' })
          }
        } else {
          reject()
          createWarningModal({ content: '没有获取到设计器信息，请检查!' })
        }
      })
    },

    /** 删除组件外放事件 */
    onDelEmit(key: string) {
      if (this.curDesignInfo) {
        const emits = this.curDesignInfo?.emits ?? []
        const index = emits.findIndex((n) => n.key === key)

        emits.splice(index, 1)
        this.curDesignInfo.emits = emits
      }
    },

    /** 新增组件外放属性 */
    onAddProp(data: BwCustomComPropInfoModel) {
      return new Promise<void>((resolve, reject) => {
        if (this.curDesignInfo) {
          const comProps = this.curDesignInfo.comProps ?? []
          const item = comProps.find((n) => n.key === data.key)
          if (!item) {
            comProps.push(data)
            this.curDesignInfo.comProps = comProps
            resolve()
          } else {
            reject()
            createWarningModal({ content: '当前属性已存在，请检查!' })
          }
        } else {
          reject()
          createWarningModal({ content: '没有获取到设计器信息，请检查!' })
        }
      })
    },

    /** 修改组件外放属性 */
    onEditProp(
      oldData: BwCustomComPropInfoModel,
      newData: BwCustomComPropInfoModel
    ) {
      return new Promise<void>((resolve, reject) => {
        if (this.curDesignInfo) {
          const comProps = this.curDesignInfo.comProps ?? []
          const index = comProps.findIndex((n) => n.key === oldData.key)
          if (index >= 0) {
            comProps[index] = newData
            this.curDesignInfo.comProps = comProps
            resolve()
          } else {
            reject()
            createWarningModal({
              content: '没有找到需要修改的外放属性，请检查!',
            })
          }
        } else {
          reject()
          createWarningModal({ content: '没有获取到设计器信息，请检查!' })
        }
      })
    },

    /** 删除组件外放属性 */
    onDelProp(key: string) {
      return new Promise<void>((resolve, reject) => {
        if (this.curDesignInfo) {
          const comProps = this.curDesignInfo.comProps ?? []
          const index = comProps.findIndex((n) => n.key === key)
          if (index >= 0) {
            comProps.splice(index, 1)
            this.curDesignInfo.comProps = comProps
            resolve()
          } else {
            reject()
            createWarningModal({ content: '没有找到需要删除的属性，请检查!' })
          }
        } else {
          reject()
          createWarningModal({ content: '没有获取到设计器信息，请检查!' })
        }
      })
    },

    /** 新增组件外放插槽 */
    onAddSlot(data: BwCustomComSlotInfoModel) {
      return new Promise<void>((resolve, reject) => {
        if (this.curDesignInfo) {
          const comSlots = this.curDesignInfo.comSlots ?? []
          const item = designUtils.findComSlotInfo(comSlots, data)
          if (!item.info) {
            comSlots.push(data)
            this.curDesignInfo.comSlots = comSlots
            resolve()
          } else {
            reject()
            createWarningModal({ content: '当前插槽已存在，请检查!' })
          }
        } else {
          reject()
          createWarningModal({ content: '没有获取到设计器信息，请检查!' })
        }
      })
    },

    /** 新增组件外放插槽 */
    onEditSlot(
      oldData: BwCustomComSlotInfoModel,
      newData: BwCustomComSlotInfoModel
    ) {
      return new Promise<void>((resolve, reject) => {
        if (this.curDesignInfo) {
          const comSlots = this.curDesignInfo.comSlots ?? []
          const info = designUtils.findComSlotInfo(comSlots, oldData)
          if (info.index >= 0) {
            comSlots[info.index] = newData
            this.curDesignInfo.comSlots = comSlots
            resolve()
          } else {
            reject()
            createWarningModal({
              content: '没有找到需要修改的外放插槽，请检查!',
            })
          }
        } else {
          reject()
          createWarningModal({ content: '没有获取到设计器信息，请检查!' })
        }
      })
    },

    /** 删除组件外放插槽 */
    onDelSlot(data: BwCustomComSlotInfoModel) {
      return new Promise<void>((resolve, reject) => {
        if (this.curDesignInfo) {
          const comSlots = this.curDesignInfo.comSlots ?? []
          const item = designUtils.findComSlotInfo(comSlots, data)
          if (item.index >= 0) {
            comSlots.splice(item.index, 1)
            this.curDesignInfo.comSlots = comSlots
            resolve()
          } else {
            reject()
            createWarningModal({ content: '没有找到需要删除的插槽，请检查!' })
          }
        } else {
          reject()
          createWarningModal({ content: '没有获取到设计器信息，请检查!' })
        }
      })
    },

    /** 设置组件属性配置信息 */
    setComPropsSetConfig(info?: BwCustomComPropSetConfig) {
      const designInfo = this.getDesignInfo
      if (designInfo) {
        designInfo.comPropsSetConfig = info
      }
    },
  },
})

export function useComDesignStoreWithOut() {
  return useComDesignStore(store)
}
